package org.game.msgBuilder;

import com.xiaoleilu.hutool.util.CollectionUtil;
import org.constant.DatingConstant;
import org.game.constant.DatingTypeConstant;
import org.game.db.bean.*;
import org.game.db.cache.CityDatingRecordCache;
import org.game.protobuf.s2c.S2CDatingMsg;
import org.game.protobuf.s2c.S2CShareMsg;
import org.game.protobuf.s2c.S2CShareMsg.RewardsMsg;

import java.util.List;
import java.util.Map;

public class DatingMsgBuilder {


    /**
     * 登录获取约会信息
     * code = 1539
     * @param player
     * @return
     */
    public static S2CDatingMsg.GetDatingInfo getDatingInfoMsg(Player player) {
        Dating dating = player.getDatingsFkPlayerId();
        S2CDatingMsg.GetDatingInfo.Builder builder = S2CDatingMsg.GetDatingInfo.newBuilder();

        if (dating != null) {
            //已经完成剧本
            if (dating.getScriptIdList() != null && dating.getScriptIdList().size() > 0) {
                builder.addAllDatingRuleCid(dating.getScriptIdList());
            }
            //结局
            if (dating.getEndNodeList() != null && dating.getEndNodeList().size() > 0) {
                builder.addAllEndings(dating.getEndNodeList());
            }
        }

        //未完成剧本
        List<CurrentScriptRecord> recordList = player.getCurrentScriptRecordsFkPlayerId();
        recordList.forEach(record -> {
            if (record.getScriptId() == 0){
                return;
            }
            builder.addNotFinishDating(getNotFinishDating(record));
        });

        //城市约会
        List<CityDatingRecord> cityDatingRecordList = CityDatingRecordCache.me().getByPlayerId(player.getId());
        if (cityDatingRecordList.size() > 0) {
            cityDatingRecordList.forEach(reserveDateRecord -> {
                builder.addCityDatingInfoList(getCityDatingInfo(S2CShareMsg.ChangeType.DEFAULT,reserveDateRecord));
            });
        }

        List<Role> roleList = player.getRolesFkPlayerId();
        for (Role role : roleList) {
            if (!CollectionUtil.isEmpty(role.getTriggerDating())){
                builder.addTriggerDating(createUpdateTriggerDatingMsg(role));
            }
        }
        return builder.build();
    }

    /**
     * 获取约会剧本
     * code = 1542
     * @param branchNodes 分支节点
     */
    public static S2CDatingMsg.DatingScriptMsg getDatingScriptMsg(int datingRuleCid,Map<Integer, List<Integer>> branchNodes) {
        S2CDatingMsg.DatingScriptMsg.Builder builder = S2CDatingMsg.DatingScriptMsg.newBuilder();
        builder.setDatingRuleCid(datingRuleCid);
        if (branchNodes != null){
            branchNodes.forEach((datingCfgId,nextNodeIds)->builder.addBranchNodes(buildBranchNode((int)datingCfgId,(List<Integer>)nextNodeIds)));
        }
        return builder.build();
    }

    /**
     * 获取对话消息
     * code = 1538
     * @param score 积分
     */
    public static S2CDatingMsg.DialogueMsg getDialogueMsg(int score) {
        S2CDatingMsg.DialogueMsg.Builder builder = S2CDatingMsg.DialogueMsg.newBuilder();
        builder.setScore(score);
        return builder.build();
    }

    /**
     * 获取 约会结算消息
     * code = 1540
     * @param score 积分
     * @param favor 好感度
     */
    public static S2CDatingMsg.DatingSettlementMsg getDatingSettlementMsg(int score, int favor, int scriptId,
                                                                          List<RewardsMsg> rewards) {
        S2CDatingMsg.DatingSettlementMsg.Builder builder = S2CDatingMsg.DatingSettlementMsg.newBuilder();
        builder.setScore(score).setFavor(favor);
        if (scriptId != 0) {
            builder.setScriptId(scriptId);
        }
        builder.addAllRewards(rewards);
        return builder.build();
    }

    public static S2CDatingMsg.CityDatingInfo getCityDatingInfo(S2CShareMsg.ChangeType ct, CityDatingRecord cityDatingRecord) {
        S2CDatingMsg.CityDatingInfo.Builder builder = S2CDatingMsg.CityDatingInfo.newBuilder();
        builder.setCt(ct)
                .setCityDatingId(cityDatingRecord.getId() + "")
                .setState(cityDatingRecord.getCityDatingRecordProxy().getState())
                .setDate((int) (cityDatingRecord.getCityDatingRecordProxy().getDatingBeginTime()/1000))
                .setDatingRuleCid(cityDatingRecord.getCid());
        if (cityDatingRecord.getCityDatingRecordProxy().getDatingTimeFrame() != null)
            builder.addAllDatingTimeFrame(cityDatingRecord.getCityDatingRecordProxy().getDatingTimeFrame());
        return builder.build();
    }

    public static S2CDatingMsg.CityDatingInfoList buildCityDatingInfoList(S2CShareMsg.ChangeType ct, List<CityDatingRecord> recordList){
        S2CDatingMsg.CityDatingInfoList.Builder builder = S2CDatingMsg.CityDatingInfoList.newBuilder();
        recordList.forEach(record -> builder.addCityDatingInfo(getCityDatingInfo(ct,record)));
        return builder.build();
    }

    /**
     * 城市约会信息列表
     */
    public static S2CDatingMsg.CityDatingInfoList buildCityDatingInfoList(List<CityDatingRecord> recordList){
        S2CDatingMsg.CityDatingInfoList.Builder builder = S2CDatingMsg.CityDatingInfoList.newBuilder();
        S2CShareMsg.ChangeType ct;
        for (CityDatingRecord record : recordList) {
            if (record.getCityDatingRecordProxy().getState() == DatingConstant.RESERVE_DATING_STATE_NO_DATING){
                ct = S2CShareMsg.ChangeType.DELETE;
            }else{
                ct = S2CShareMsg.ChangeType.UPDATE;
            }
            builder.addCityDatingInfo(getCityDatingInfo(ct,record));
        }
        return builder.build();
    }

    /**
     * 获取未完成约会信息
     *
     * @param record 当前约会记录
     */
    private static S2CDatingMsg.NotFinishDating getNotFinishDating(CurrentScriptRecord record) {
        if (record != null && record.getScriptId() != 0) {
            S2CDatingMsg.NotFinishDating.Builder notFinishBuilder = S2CDatingMsg.NotFinishDating.newBuilder();
            notFinishBuilder.setScore(record.getScore())
                    .setDatingRuleCid(record.getScriptId())
                    .setDatingType(record.getDatingType())
                    .addAllRoleCid(record.getRoleIds())
                    .setCurrentNodeId(record.getCurrentCid());

            if (record.getDatingType() != DatingTypeConstant.DATING_TYPE_MAIN) {
                record.getCurrentScript().forEach((datingCfgId,nextNodeIds)->notFinishBuilder.addBranchNodes(buildBranchNode((int)datingCfgId,(List<Integer>)nextNodeIds)));
            }
            for (Object nodeId : record.getSelectedNode()) {
                notFinishBuilder.setSelectedNode((Integer) nodeId);
            }
            return notFinishBuilder.build();
        }
        return null;
    }

    /**
     * 获取分支节点消息
     *
     * @param branchNodes 分支节点
     */
    private static S2CDatingMsg.BranchNodes getBranchNodes(Map<Integer, List<Integer>> branchNodes) {
        S2CDatingMsg.BranchNodes.Builder builder = S2CDatingMsg.BranchNodes.newBuilder();
        branchNodes.forEach((datingCfgId, branchNodeIds) -> {
            S2CDatingMsg.BranchNode.Builder branchNodeBuilder = S2CDatingMsg.BranchNode.newBuilder();
            branchNodeBuilder.setDatingId(datingCfgId);
            branchNodeBuilder.addAllNextNodeIds(branchNodeIds);
            builder.addBranchNodes(branchNodeBuilder);
        });
        return builder.build();
    }

    private static S2CDatingMsg.BranchNode buildBranchNode(int datingCfgId, List<Integer> nextNodeIds){
        S2CDatingMsg.BranchNode.Builder branchNodeBuilder = S2CDatingMsg.BranchNode.newBuilder();
        return branchNodeBuilder.setDatingId(datingCfgId)
                .addAllNextNodeIds(nextNodeIds)
                .build();
    }

    public static S2CDatingMsg.UpdateTriggerDating createUpdateTriggerDatingMsg(Role role){
        S2CDatingMsg.UpdateTriggerDating.Builder builder = S2CDatingMsg.UpdateTriggerDating.newBuilder();
        return builder.setRoleId(role.getCid())
                .addAllDatingRuleCid(role.getTriggerDating())
                .build();
    }

    public static S2CDatingMsg.DatingFail createDatingFailMsg(int datingRuleCid){
        S2CDatingMsg.DatingFail.Builder builder = S2CDatingMsg.DatingFail.newBuilder();
        return builder.setDatingRuleCid(datingRuleCid)
                .build();
    }
}
